home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
prog
/
asmclock.arj
/
ASMCLOCK.ASM
next >
Wrap
Assembly Source File
|
1991-05-16
|
15KB
|
380 lines
;----------------------------------------------------------------------------;
; ASMCLOCK.ASM ;
;----------------------------------------------------------------------------;
; ;
; MASM 6.0 Translation of Charles Petzold's DIGCLOCK.C Digital Clock Program ;
; ;
;----------------------------------------------------------------------------;
.8086
.model small, pascal, os_dos
include windows.inc ; Converted from WINDOWS.H
include time.inc ; Converted w/H2INC
include stdio.inc ; Converted w/H2INC
;------ PROLOGUE.INC ------;
?WP_INCBP = 1 ; INC BP on all far procs ;
?WP_LOADDS = 1 ; LOAD DS on all far procs ;
include prologue.inc ;--------------------------;
;----------------------------------------------------------------------------;
; Prototypes ;
; ;
; Function/Procedure prototypes are new to MASM 6.0. They have the same ;
; pupose as do prototypes in other High-Level languages. Note the new ;
; data initializers and the user defined types (HWND, and PINT). ;
;----------------------------------------------------------------------------;
WndProc PROTO FAR PASCAL, :HWND, :WORD, :SWORD, :SDWORD
SizeTheWindow PROTO, :PINT, :PINT, :PINT, :PINT
SetInternational PROTO
;----------------------------------------------------------------------------;
; Numeric Equates ;
; ;
; EQU is now recommended to be used with numeric equates only. If you need ;
; text equates, use the new directive, TEXTEQU. This removes a lot of the ;
; ambiguities associated with EQU for both text and numbers. ;
;----------------------------------------------------------------------------;
AMPMBUFLEN EQU 5
BUFLEN EQU 25
;----------------------------------------------------------------------------;
; Data Segment ;
; ;
; Note the new data type mnemonics BYTE (unsigned byte), and SBYTE (signed). ;
; There are also WORD, REAL4, REAL8, and, REAL10. These along with the new ;
; TYPEDEF keyword you can create your own data types as you can with other ;
; High-Level languages. ;
;----------------------------------------------------------------------------;
.data
sDate SBYTE ?,?
sTime SBYTE ?,?
sAMPM SBYTE 2 dup (AMPMBUFLEN dup(?))
iDate SWORD ?
iTime SWORD ?
szAppName BYTE "MASMClock",0
szTooManyTimers BYTE "Too many clocks or timers!",0
szDisplay BYTE "DISPLAY", 0
szIntl BYTE "intl", 0
sziDate BYTE "iDate", 0
sziTime BYTE "iTime", 0
szsDate BYTE "sDate", 0
szsTime BYTE "sTime", 0
szs1159 BYTE "s1159", 0
szs2359 BYTE "s2359", 0
szAM BYTE "am", 0
szPM BYTE "pm", 0
szSlash BYTE "/", 0
szColon BYTE ":", 0
szWday SBYTE "Sun",0,"Mon",0,"Tue",0,"Wed",0,"Thu",0,"Fri",0,"Sat",0
DateFmt SBYTE " %s %d%s%02d%s%02d ",13,10,0
TimeFmt1 SBYTE " %02d%s%02d%s%02d ",0
TimeFmt2 SBYTE " %d%s%02d%s%02d %s ",0
;----------------------------------------------------------------------------;
; Code Segment ;
;----------------------------------------------------------------------------;
.code
extern __ACRTUSED:ABS ; Let the linker know we use the
; C runtimes.
;----------------------------------------------------------------------------;
; WinMain ;
;----------------------------------------------------------------------------;
WinMain PROC, hInstance:HANDLE, hPrevInstance:HANDLE,
lpszCmdLine:LPSTR, nCmdShow:SWORD
LOCAL msg:MSG,
xStart:SWORD, yStart:SWORD, xClient:SWORD, yClient:SWORD,
wndclass:WNDCLASS
;
;--- Check for previous instances
;
.IF (hPrevInstance == 0)
mov wndclass.style, (CS_HREDRAW OR CS_VREDRAW)
mov WORD PTR wndclass.lpfnWndProc, LROFFSET WndProc
mov WORD PTR wndclass.lpfnWndProc+2, SEG WndProc
xor ax,ax
mov wndclass.cbClsExtra, ax
mov wndclass.cbWndExtra, ax
mov ax, hInstance
mov wndclass.hInstance, ax
INVOKE LoadCursor, NULL, IDC_ARROW
mov wndclass.hCursor, ax
INVOKE GetStockObject, WHITE_BRUSH
mov wndclass.hbrBackground, ax
xor ax, ax
mov WORD PTR wndclass.lpszMenuName, ax
mov WORD PTR wndclass.lpszMenuName+2, ax
mov WORD PTR wndclass.lpszClassName, OFFSET szAppName
mov WORD PTR wndclass.lpszClassName+2, ds
INVOKE RegisterClass, ADDR wndclass
.IF (ax == 0)
mov ax, FALSE
jmp doRet
.ENDIF
.ENDIF ;--- End of IF (hPrevInstance == 0)
INVOKE SizeTheWindow, ADDR xStart, ADDR yStart,
ADDR xClient, ADDR yClient
mov ax, offset szAppName
INVOKE CreateWindow, ds::ax, ds::ax,
WS_POPUP OR WS_DLGFRAME OR WS_SYSMENU,
xStart, yStart,
xClient, yClient,
NULL, NULL,
hInstance,
NULL
mov si, ax ; keep hWnd in SI
INVOKE SetTimer, si, 1, 1000, NULL
.IF (ax == 0)
INVOKE MessageBox, si,
ADDR szTooManyTimers,
ADDR szAppName,
MB_ICONEXCLAMATION OR MB_OK
mov ax, FALSE
jmp doRet
.ENDIF
INVOKE ShowWindow, si, SW_SHOWNOACTIVATE
INVOKE UpdateWindow, si
;
;----Message Loop
;
.WHILE TRUE
INVOKE GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (ax == 0)
INVOKE TranslateMessage, ADDR msg
INVOKE DispatchMessage, ADDR msg
.ENDW
;
;---Return to Windows
;
mov ax, msg.wParam
doRet:
ret
WinMain ENDP
;----------------------------------------------------------------------------;
; SizeTheWindow ;
;----------------------------------------------------------------------------;
SizeTheWindow PROC USES si di, pxStart:PINT, pyStart:PINT, pxClient:PINT, pyClient:PINT
LOCAL tmetric:TEXTMETRIC
xor dx, dx
INVOKE CreateIC, ADDR szDisplay, dx::dx, dx::dx, dx::dx
INVOKE GetTextMetrics, ax, ADDR tmetric
INVOKE DeleteDC, ax
INVOKE GetSystemMetrics, SM_CXDLGFRAME ; Set width
shl ax, 1
mov bx, tmetric.tmAveCharWidth
mov cl, 4
shl bx, cl
add ax, bx
mov si, pxClient
mov [si], ax
INVOKE GetSystemMetrics, SM_CXSCREEN
mov si, pxClient
sub ax, [si]
mov si, pxStart
mov [si], ax
INVOKE GetSystemMetrics, SM_CYDLGFRAME ; Set Height
shl ax, 1
mov bx, tmetric.tmHeight
shl bx, 1
add ax, bx
mov si, pyClient
mov [si], ax
INVOKE GetSystemMetrics, SM_CYSCREEN
mov si, pyClient
sub ax, [si]
mov si, pyStart
mov [si], ax
ret
SizeTheWindow ENDP
;----------------------------------------------------------------------------;
; SetInternational ;
;----------------------------------------------------------------------------;
SetInternational PROC
xor dx, dx
INVOKE GetProfileInt, ADDR szIntl, ADDR sziDate, dx
mov iDate, ax
INVOKE GetProfileInt, ADDR szIntl, ADDR sziTime, 0
mov iTime, ax
INVOKE GetProfileString, ADDR szIntl, ADDR szsDate, ADDR szSlash, ADDR sDate, 2
INVOKE GetProfileString, ADDR szIntl, ADDR szsTime, ADDR szColon, ADDR sTime, 2
INVOKE GetProfileString, ADDR szIntl, ADDR szs1159, ADDR szAM, ADDR sAMPM, AMPMBUFLEN
INVOKE GetProfileString, ADDR szIntl, ADDR szs2359, ADDR szPM, ADDR sAMPM+AMPMBUFLEN, AMPMBUFLEN
ret
SetInternational ENDP
;----------------------------------------------------------------------------;
; WndPaint ;
;----------------------------------------------------------------------------;
WndPaint PROC USES si di, hWnd:HWND, hDC:HDC
LOCAL cBuffer[40]:BYTE,
lTime:SDWORD,
rect:RECT,
nLength:SWORD,
datetime:PTR tm
xor dx, dx
INVOKE time, ADDR lTime ; C "time" runtime
INVOKE localtime, ADDR lTime ; C "localtime" runtime
mov datetime, ax
mov bx, ax ; WDAY * 4
ASSUME bx:PTR tm ; Assumes that bx is
; a pointer to the
; structure "tm"
mov si, [bx].tm_wday
shl si, 1
shl si, 1
.IF (iDate == 1) ; cx == 1st date pos
mov cx, [bx].tm_mday ; dx == 2nd date pos
mov dx, [bx].tm_mon ; di == 3rd date pos
inc dx
mov di, [bx].tm_year
.ELSEIF (iDate == 2)
mov cx, [bx].tm_year
mov dx, [bx].tm_mon
inc dx
mov di, [bx].tm_mday
.ELSE
mov cx, [bx].tm_mon
inc cx
mov dx, [bx].tm_mday
mov di, [bx].tm_year
.ENDIF
INVOKE sprintf, ADDR cBuffer, ADDR DateFmt , ADDR szWday[si],
cx, ADDR sDate, dx, ADDR sDate, di
mov nLength, ax
mov bx, datetime
mov si, nLength
.IF (iTime == 1)
INVOKE sprintf, ADDR cBuffer[si], ADDR TimeFmt1, [bx].tm_hour,
ADDR sTime, [bx].tm_min, ADDR sTime, [bx].tm_sec
add nLength,ax
.ELSE
mov ax, [bx].tm_hour
push ax
xor dx, dx
mov di, 12
div di
xor dx, dx
mov cx, AMPMBUFLEN
mul cx
mov di, ax
pop ax ; ax == [bx].tm_hour
xor dx, dx
mov cx, 12
div cx
.IF (dx == 0)
mov cx, 12
.ELSE
mov cx, dx
.ENDIF
INVOKE sprintf, ADDR cBuffer[si], ADDR TimeFmt2,
cx, ADDR sTime, [bx].tm_min, ADDR sTime, [bx].tm_sec,
ADDR sAMPM[di]
.ENDIF
ASSUME bx:NOTHING
INVOKE GetClientRect, hWnd, ADDR rect
INVOKE DrawText, hDC, ADDR cBuffer, -1, ADDR rect,
(DT_CENTER OR DT_NOCLIP)
ret
WndPaint ENDP
;----------------------------------------------------------------------------;
; WndProc ;
;----------------------------------------------------------------------------;
WndProc PROC FAR PASCAL, hWnd:HWND, iMessage:WORD, wParam:SWORD, lParam:SDWORD
LOCAL hDC:HDC, ps:PAINTSTRUCT
.IF (iMessage == WM_CREATE)
INVOKE SetInternational
.ELSEIF (iMessage == WM_TIMER)
INVOKE InvalidateRect, hWnd, NULL, FALSE
.ELSEIF (iMessage == WM_PAINT)
INVOKE BeginPaint, hWnd, ADDR ps
mov hDC, ax
INVOKE WndPaint, hWnd, hDC
INVOKE EndPaint, hWnd, ADDR ps
.ELSEIF (iMessage == WM_WININICHANGE)
INVOKE SetInternational
INVOKE InvalidateRect, hWnd, NULL, TRUE
.ELSEIF (iMessage == WM_DESTROY)
INVOKE KillTimer, hWnd, 1
INVOKE PostQuitMessage, 0
.ELSE
INVOKE DefWindowProc, hWnd, iMessage, wParam, lParam
jmp doRet
.ENDIF
mov ax, 0
cwd
doRet:
ret
WndProc ENDP
;----------------------------------------------------------------------------
END